package com.elastic.test;

import com.elastic.model.Product;
import com.google.gson.Gson;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.Kv;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.*;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.Test;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: 李德才
 * @description:
 * @create: 2021-04-10 16:59
 **/
public class ElasticSearchHighLevel_crud {
    public static RestHighLevelClient CLIENT = null;
    public static final String IP_ADDR = "192.168.31.100";
    public static final String HTTP = "http";
    public static final String INDEX_NAME = "test_index";

    static {
        CLIENT = new RestHighLevelClient(RestClient.builder(new HttpHost(IP_ADDR, 9200, HTTP), new HttpHost(IP_ADDR, 9201, HTTP)));
    }

    @Test
    public void createIndex() throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("test_index");
        createIndexRequest.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 2));
        CreateIndexResponse createIndexResponse = CLIENT.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        if (createIndexResponse.isAcknowledged()) {
            System.err.println("创建Index成功");
        } else {
            System.err.println("创建Index失败");
        }
        CLIENT.close();
    }

    @Test
    public void getIndex() throws IOException {
        GetIndexRequest getIndexRequest = new GetIndexRequest(INDEX_NAME);
        GetIndexResponse getIndexResponse = CLIENT.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        String[] indices = getIndexResponse.getIndices();
        for (String indexName : indices) {
            System.err.println(" index name ==> " + indexName);
        }
        CLIENT.close();
    }

    @Test
    public void deleteIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(INDEX_NAME);
        AcknowledgedResponse delete = CLIENT.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.err.println("删除索引" + (delete.isAcknowledged() ? "成功" : "失败"));
        CLIENT.close();
    }

    @Test
    public void insertData() throws IOException {
        List<Product> list = DataForMySql.getList();
        IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
        Product product = list.get(0);
        indexRequest.id(product.getId().toString());

        /**
         *  indexRequest.source(new Gson().toJson(product));
         * 这样写会报错 ： //The number of object passed must be even but was [1]
         * 因为源码中认为下面的写法只有 key ,没有 value ,
         * 这样写就可以 indexRequest.source("name","小米手机");
         * 原因：担心 source[i++].toString() 取不到值
         *  for(int i = 0; i < source.length; ++i) {
         *      builder.field(source[i++].toString(), source[i]);
         *  }
         **/
//        但是如果指定了 JSON 类型就不需要考虑这个问题
        indexRequest.source(new Gson().toJson(product), XContentType.JSON);
        IndexResponse indexResponse = CLIENT.index(indexRequest, RequestOptions.DEFAULT);
        System.err.println(indexResponse);
        CLIENT.close();
    }

    @Test
    public void batchInsertData() throws IOException {
        BulkRequest request = new BulkRequest(INDEX_NAME);
        List<Product> list = DataForMySql.getList();
        for (Product product : list) {
            request.add(new IndexRequest().source(new Gson().toJson(product), XContentType.JSON));
        }
        BulkResponse bulkItemResponses = CLIENT.bulk(request, RequestOptions.DEFAULT);
        System.err.println(bulkItemResponses.getItems().length);
        CLIENT.close();
    }

    @Test
    public void getById() throws IOException {
        GetRequest getRequest = new GetRequest(INDEX_NAME, "H4pEu3gB7OjzT7KL9Xr3");
//        String[] includes = {"name", "price"};
//        String[] excludes = {};
//        FetchSourceContext fetchSourceContext = new FetchSourceContext(true,includes,excludes);
        FetchSourceContext fetchSourceContext = new FetchSourceContext(true);
//        getRequest.fetchSourceContext(fetchSourceContext);
        GetResponse getResponse = CLIENT.get(getRequest, RequestOptions.DEFAULT);
        System.err.println(getResponse);
        CLIENT.close();
    }


    @Test
    public void deleteById() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(INDEX_NAME, "H4pEu3gB7OjzT7KL9Xr3");
        DeleteResponse deleteResponse = CLIENT.delete(deleteRequest, RequestOptions.DEFAULT);
        System.err.println(deleteResponse);
        CLIENT.close();
    }


    @Test
    public void multiGetById() throws IOException {
        MultiGetRequest multiGetRequest = new MultiGetRequest();
        multiGetRequest.add(INDEX_NAME, "HopEu3gB7OjzT7KL9Xr3");
        multiGetRequest.add(new MultiGetRequest.Item(INDEX_NAME, "IopEu3gB7OjzT7KL9Xr3"));
        MultiGetResponse multiGetItemResponses = CLIENT.mget(multiGetRequest, RequestOptions.DEFAULT);
        MultiGetItemResponse[] responses = multiGetItemResponses.getResponses();
        for (MultiGetItemResponse multiGetItemResponse : responses) {
//            System.err.println(multiGetItemResponse.getResponse().getSourceAsString());
            System.err.println(multiGetItemResponse.getResponse().getSourceAsMap());
        }
        CLIENT.close();
    }


    @Test
    public void updateByQuery() throws IOException {
        UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(INDEX_NAME);
        //默认情况下，版本冲突会中止 UpdateByQueryRequest 进程，但是你可以用以下命令来代替
        //设置版本冲突继续
        updateByQueryRequest.setConflicts("proceed");
        updateByQueryRequest.setQuery(QueryBuilders.matchQuery("attrs.name", "红米耳机"));
        updateByQueryRequest.setScript(new Script(ScriptType.INLINE, "painless", "ctx._source.attrs.desc+='#';", Collections.emptyMap()));
        BulkByScrollResponse bulkByScrollResponse = CLIENT.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
        System.err.println(bulkByScrollResponse);
        System.err.println(bulkByScrollResponse.getStatus());
        CLIENT.close();
    }


    @Test
    public void searchQuery() throws IOException {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("attrs.name", "红米耳机");
        boolQueryBuilder.should(matchQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(100);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = CLIENT.search(searchRequest, RequestOptions.DEFAULT);
        System.err.println(searchResponse);
        System.err.println(searchResponse.getHits().getHits().toString());
    }


}
